
  {COMMAND.PA2}

  {Set_Token_Parameters}

  PROCEDURE Set_Token_Parameters;
  VAR i : Token;

  BEGIN
    FOR i := AtLocation TO DoneWithTurn
    DO P[i] := 1;                 {set all parameter values to 1}

    {Now deal with exceptions, i.e., parameter values of 0 and 2}

    {*************************************************************************}
    {*                C O N D I T I O N    T O K E N S                       *}
    {*************************************************************************}

    {**********************   PLAYER CONDITIONS   ****************************}
    {                 Type of   Number Of}
    {TOKEN NAME     Parameters Parameters     Explanation}
    {=============== =============  ==== ====================================}
    P[IsCarryingSomething {None} ] := 0; {Player is carrying something}
    P[IsCarryingNothing {None} ] := 0; {Player is carrying nothing}
    {worth at least PTS# points}
    P[IsWearingSomething {None} ] := 0; {Player is wearing something}
    P[IsWearingNothing {None} ] := 0; {Player is wearing nothing}
    P[FirstVisitToRoom {None} ] := 0; {Player is in current room for first time}
    P[NewLife {None} ] := 0;      {Player is starting game or has just been resurrected}

    {**********************   ITEM CONDITIONS   **********************************}
    {                 Type of   Number Of}
    {TOKEN NAME     Parameters Parameters     Explanation}
    {=============== =============  ==== ========================================}
    P[IsLocated {ITEM#  loc#} ] := 2; {ITEM# is located in room loc#}
    P[Together {ITEM# ITEM#} ] := 2; {ITEM# and ITEM# are in same place}

    {*********************   NOUN CONDITIONS   *******************************}
    {                 Type of   Number Of}
    {TOKEN NAME     Parameters Parameters     Explanation}
    {=============== =============  ==== ====================================}
    P[NOUNPresent {none} ] := 0;  {NOUN ITEM is in room, carried or worn}
    P[NOUNIsWearing {none} ] := 0; {NOUN ITEM is being worn}
    P[NOUNIsCarrying {none} ] := 0; {NOUN ITEM is being carried}
    P[NOUNIsNowhere {none} ] := 0; {NOUN ITEM is located NOWHERE (room 0)}
    P[NOUNIsSomewhere {none} ] := 0; {NOUN ITEM is located somewhere}
    P[NOUNInRoom {none} ] := 0;   {NOUN ITEM is located in current room}
    P[NOUNIsON {none} ] := 0;     {NOUN ITEM is ON}
    P[NOUNIsOFF {none} ] := 0;    {NOUN ITEM is OFF}
    P[NOUNIsOpen {none} ] := 0;   {NOUN ITEM is Open}
    P[NOUNIsClosed {none} ] := 0; {NOUN ITEM is Closed}
    P[NOUNIsLocked {none} ] := 0; {NOUN ITEM is Locked}
    P[NOUNIsUnLocked {none} ] := 0; {NOUN ITEM is UnLocked}
    P[NOUNIsEdible {none} ] := 0; {NOUN ITEM is Edible}
    P[NOUNIsDrinkable {none} ] := 0; {NOUN ITEM is Drinkable}
    P[NOUNIsPoisonous {none} ] := 0; {NOUN ITEM is Poisonous}
    P[NOUNIsMovable {none} ] := 0; {NOUN ITEM is Movable}

    {*****************   MISCELLANEOUS CONDITIONS   **************************}
    {                 Type of   Number Of}
    {TOKEN NAME     Parameters Parameters     Explanation}
    {=============== =============  ==== ====================================}
    P[LightPresent {none} ] := 0; {Room has necessary light}
    P[RoomNeedsLight {none} ] := 0; {Room needs a light}
    P[AnswerIsCorrect {none} ] := 0; {last answer was correct}
    P[AnswerIsWrong {none} ] := 0; {last answer was wrong}
    P[CounterEquals {ctr# num} ] := 2; {Counter # is equal to num}
    P[CounterGT {ctr# num} ] := 2; {Counter # is greater than num}
    P[CounterLT {ctr# num} ] := 2; {Counter # is less than num}
    P[VariableEquals {var# num} ] := 2; {Variable # is equal to num}
    P[VariableGT {var# num} ] := 2; {Variable # is greater than num}
    P[VariableLT {var# num} ] := 2; {Variable # is less than num}
    P[CompareVariables {V1 V2} ] := 2; {TRUE if V1 < V2 }
    P[VariableChance {V N} ] := 2; {TRUE if V < Random(1..N)}
    P[NamePresent {none} ] := 0;  {TRUE if Name being addressed is at location or No Name addressed}
    P[PromptForYES {none} ] := 0; {Prompts for Y or N -- Ok if Yes}
    P[PromptForNO {none} ] := 0;  {Prompts for Y or N -- Ok if No}
    P[VerbIsDirection {none} ] := 0; {Verb is movement or direction}
    P[NounIsCreature] := 0;       {TRUE if noun is a creature}
    P[ObjectIsCreature] := 0;     {TRUE if object is a creature}
    P[ObjectPresent] := 0;        {TRUE if object is present in room}
    P[LogicalNOT {none} ] := 0;   {Logical NOT of current condition}
    P[LogicalOR {none} ] := 0;    {Logical OR of conditions}

    {*************************************************************************}
    {*                    A C T I O N     T O K E N S                        *}
    {*************************************************************************}

    {******************* PLAYER ACTION TOKENS ********************************}
    {                 Type of   Number Of}
    {TOKEN NAME     Parameters Parameters     Explanation}
    {=============== =============  ==== ====================================}
    P[GoToRandomRoom {R1 R2} ] := 2; {Send player to Room >= R1 and <= R2}
    P[SendToVariableRoom] := 2;   {Item# Var# -- will send Item# to room number Var#}
    P[GetNOUN {none} ] := 0;      {NOUN is now being carried}
    P[WearNOUN {none} ] := 0;     {NOUN is now being worn}
    P[DropNOUN {none} ] := 0;     {Drops NOUN into current room}
    P[RemoveNOUN {none} ] := 0;   {Removes NOUN and drops into room}
    P[DropEverything {none} ] := 0; {Drop all items being carried}
    P[RemoveEverything {none} ] := 0; {Remove all items being worn}
    P[KillPlayer {none} ] := 0;   {Makes player dead}

    {************** ITEM/NOUN/LOCATION ACTION TOKENS *************************}
    {                 Type of   Number Of}
    {TOKEN NAME     Parameters Parameters     Explanation}
    {=============== =============  ==== ====================================}
    P[PutNOUNInCurrentRoom {none} ] := 0; {Put NOUN in current room}
    P[SendToRoom {ITEM# loc#} ] := 2; {Put ITEM# in room loc#}
    P[SendTreasuresToRoom {loc# pts#} ] := 2; {Send all carried ITEMs whose}
    {points > pts# to loc#}
    P[RelocateAll {loc1 loc2} ] := 2; {Move all items at loc1 to loc2}
    P[DestroyNOUN {none} ] := 0;  {NOUN is now NOWHERE (room 0)}
    P[SwapLocations {ITEM1 ITEM2} ] := 2; {swap locations of ITEM1 & ITEM2}
    P[SendToItem {ITEM1 ITEM2} ] := 2; {Put ITEM1 in location of ITEM2}
    P[ReDirectTo] := 0;           {Re-Direct command to different VERB-NOUN-OBJECT}
    P[RandomMessage] := 2;        {Select message between Num1 and Num2 and print it}
    P[OpenNOUN {none} ] := 0;     {NOUN is now open}
    P[CloseNOUN {none} ] := 0;    {NOUN is now closed}
    P[LockNOUN {none} ] := 0;     {NOUN is now locked}
    P[UnlockNOUN {none} ] := 0;   {NOUN is now unlocked}

    {**************** MISCELLANEOUS ACTION TOKENS ****************************}
    {                 Type of   Number Of}
    {TOKEN NAME     Parameters Parameters     Explanation}
    {=============== =============  ==== ====================================}
    P[ShowScore {none} ] := 0;    {Show current SCORE}
    P[ShowInventory {none} ] := 0; {Show current INVENTORY}
    P[WaitForReturn {none} ] := 0; {Prints 'Hit RETURN' message}
    P[TimePasses {none} ] := 0;   {Show 'Time passes...' message}
    P[CLEARSCREEN {none} ] := 0;  {Clears screen}
    P[LookAtRoom {none} ] := 0;   {Cause a VERBOSE look at room}
    P[BlankLine {none} ] := 0;    {Prints a blank line}
    P[Tone {H M} ] := 2;          {makes a sound at H hertz for M milliseconds}
    P[GetNumberInput {num1 num2} ] := 2; {Prompt for player to input a number}
    {where num1 <= number <= num2}
    {if num1=num2, then no range will be given in prompt}
    P[ChangePassageway {dir# loc#} ] := 2; {Creates or closes a passageway}
    {from current_room to loc# via dir#}
    {dir# = 1 = north ... 12 = exit}
    P[SetVariableTo {var# num#} ] := 2; {Set Variable var# to num#}
    P[AddToVariable {var# num#} ] := 2; {Add num# to Variable var#}
    P[SubtractFromVariable {var# num#} ] := 2; {Subtract num# from Variable #}
    P[AddVariables {V1 V2} ] := 2; {Add V2 to V1 and put answer in V1}
    P[SubtractVariables {V1 V2} ] := 2; {Subtract V2 from V1 and put answer in V1}
    P[RandomVariable {V N} ] := 2; {Set variable V to random number [1 .. N]}
    P[QuitThisCMD {none} ] := 0;  {Quit evaluating this CMD}
    P[QuitAllCMDs {none} ] := 0;  {Finished with all special CMDs}
    P[DoneWithTurn {none} ] := 0; {All Done this turn -- get input next}
    P[WinGame {none} ] := 0;      {Player wins game at end of turn}
    P[EndGame {none} ] := 0;      {game ends at end of turn}
  END;                            {Set_Token_Parameters}


  {        READ_Special_CMDS}
  {Read Special_CMD file (if it exists) and}
  {initialize the various special commands}
  PROCEDURE Read_Special_CMDs;
  LABEL Exit, DoneWithFile;
  VAR i, j, n1, DataElement : Integer;
    sentence : s;
    fname, st, st2, verb, noun, prep, object_word : words;
    ErrorInCommand : Boolean;

    {Process Token}
    PROCEDURE Process(cmdTOKEN : Token);
    VAR NumPara : Integer;
    BEGIN                         {Process}
      IF NOT ErrorInCommand THEN  {process only legal commands}
        BEGIN
          NumPara := P[cmdTOKEN];
          IF ((DataElement+NumPara) > MaxSizeCommand) THEN
            BEGIN
              ErrorInCommand := True;
              WriteLn('For Command # ', Last_CMD, '  ', verb, ' ', noun, ' ', object_word);
              WriteLn('Maximum DATA size exceeded');
            END
          ELSE
            BEGIN
              SpecialCMD[Last_CMD]^.Data[DataElement] := Ord(cmdTOKEN);
              IF NumPara > 0 THEN
                BEGIN
                  sentence := But_First(sentence); {strips off Token}
                  SpecialCMD[Last_CMD]^.Data[DataElement+1] := Value(sentence);
                  IF ((cmdTOKEN = PrintMessage) AND (SpecialCMD[Last_CMD]^.Data[DataElement+1] = 0)) THEN
                    BEGIN
                      ErrorInCommand := True;
                      WriteLn('For Command # ', Last_CMD, '  ', verb, ' ', noun, ' ', object_word);
                      WriteLn('PrintMessage 0');
                    END;
                END;
              IF NumPara = 2 THEN
                BEGIN
                  sentence := But_First(sentence); {strips off first parameter}
                  SpecialCMD[Last_CMD]^.Data[DataElement+2] := Value(sentence);
                END;
              DataElement := DataElement+NumPara+1;
              {advance to place for next condition/action}
            END;                  {ELSE}
        END;                      {NOT ErrorInCommand}
    END;                          {Process}

  BEGIN                           {read_Special_CMDs}
    Skip_A_Line := False;
    fname := Command_File_Name;
    Last_CMD := 0;                {zero upper index limit to start with}
    IF NOT File_Exists(fname) THEN
      BEGIN
        Any_Special_Cmds := False; {no special commands - so set flag and exit}
        GOTO Exit;
      END;
    WriteLn;
    WriteLn('Please be patient, just a minute or two longer!');
    Any_Special_Cmds := True;     {special commands - so set flag}
    Assign(datafile, Command_File_Name);
    Reset(datafile);
    {zero out the command information}
    FOR i := 1 TO MaxCommand DO
      BEGIN
        New(SpecialCMD[i]);       {must create space in heap}
        WITH SpecialCMD[i]^ DO
          BEGIN
            VerbNum := 0;
            VerbCMD := '';
            NounCMD := '';
            ObjectCMD := '';
            FOR j := 1 TO MaxSizeCommand DO
              Data[j] := Ord(QuitThisCMD);
          END;                    {WITH}
      END;                        {for i := 1 to MaxCommand}

    ErrorInCommand := False;      {to start with}
    REPEAT                        {until (sentence = 'END OF FILE') or (EOF(datafile))}
      ReadLn(datafile, sentence);
      Capitalize(sentence);
      st := first_word(sentence);
      IF (EOF(datafile)) THEN GOTO DoneWithFile;
      IF (st = 'COMMAND') OR (st = 'C_') THEN
        BEGIN
          IF NOT ErrorInCommand THEN Last_CMD := Last_CMD+1; {update upper limit number}
          {If last command was illegal, ignore it and write over it}
          sentence := But_First(sentence);
          IF Last_CMD > MaxCommand THEN
            BEGIN
              WriteLn('Too many commands!  Processing halted');
              Halt;
            END;
          n1 := 0;
          verb := 'ANY';
          noun := 'ANY';
          object_word := 'ANY';
          st2 := first_word(sentence);
          IF st2 <> '' THEN
            BEGIN
              ErrorInCommand := False; {to start with}
              Handle_Word_Combinations(sentence);
              CheckForName(sentence);
              Parse(sentence, verb, noun, prep, object_word, ErrorInCommand);
              IF verb = '' THEN verb := 'ANY';
              IF noun = '' THEN noun := 'ANY';
              IF object_word = '' THEN object_word := 'ANY';
              n1 := Verb_Number(verb);
              IF NameNum <> 0 THEN n1 := NameNum; {Name used for sort key}
              IF ErrorInCommand THEN
                BEGIN
                  WriteLn('in COMMAND ', sentence);
                  WriteLn;
                END;
            END;
          SpecialCMD[Last_CMD]^.VerbNum := n1;
          SpecialCMD[Last_CMD]^.VerbCMD := verb;
          SpecialCMD[Last_CMD]^.NounCMD := noun;
          SpecialCMD[Last_CMD]^.ObjectCMD := object_word;
          DataElement := 1;
          REPEAT                  {within COMMAND}
            ReadLn(datafile, sentence);
            Capitalize(sentence);
            st := first_word(sentence);
            IF st = 'NOT' THEN
              BEGIN
                Process(LogicalNOT);
                sentence := But_First(sentence);
                st := first_word(sentence);
              END;
            IF st = 'ATLOCATION' THEN
              Process(AtLocation)
            ELSE IF st = 'ATLOCATIONGT' THEN
              Process(AtLocationGT)
            ELSE IF st = 'ATLOCATIONLT' THEN
              Process(AtLocationLT)
            ELSE IF st = 'FIRSTVISITTOROOM' THEN
              Process(FirstVisitToRoom)
            ELSE IF st = 'NEWLIFE' THEN
              Process(NewLife)
            ELSE IF st = 'LOADWEIGHTEQUALS' THEN
              Process(LoadWeightEquals)
            ELSE IF st = 'LOADWEIGHTGT' THEN
              Process(LoadWeightGT)
            ELSE IF st = 'LOADWEIGHTLT' THEN
              Process(LoadWeightLT)
            ELSE IF st = 'PRESENT' THEN
              Process(Present)
            ELSE IF st = 'ISWEARING' THEN
              Process(IsWearing)
            ELSE IF st = 'ISWEARINGNOTHING' THEN
              Process(IsWearingNothing)
            ELSE IF st = 'ISWEARINGSOMETHING' THEN
              Process(IsWearingSomething)
            ELSE IF st = 'ISCARRYING' THEN
              Process(IsCarrying)
            ELSE IF st = 'ISCARRYINGSOMETHING' THEN
              Process(IsCarryingSomething)
            ELSE IF st = 'ISCARRYINGNOTHING' THEN
              Process(IsCarryingNothing)
            ELSE IF st = 'ISCARRYINGTREASURE' THEN
              Process(IsCarryingTreasure)
            ELSE IF st = 'LIGHTPRESENT' THEN
              Process(LightPresent)
            ELSE IF st = 'ROOMNEEDSLIGHT' THEN
              Process(RoomNeedsLight)
            ELSE IF st = 'ISNOWHERE' THEN
              Process(IsNowhere)
            ELSE IF st = 'ISSOMEWHERE' THEN
              Process(IsSomewhere)
            ELSE IF st = 'INROOM' THEN
              Process(InRoom)
            ELSE IF st = 'ISLOCATED' THEN
              Process(IsLocated)
            ELSE IF st = 'TOGETHER' THEN
              Process(Together)
            ELSE IF st = 'ISON' THEN
              Process(IsON)
            ELSE IF st = 'ISOFF' THEN
              Process(IsOFF)
            ELSE IF st = 'ISGROUPMEMBER' THEN
              Process(IsGroupMember)
            ELSE IF st = 'ISOPEN' THEN
              Process(IsOpen)
            ELSE IF st = 'ISCLOSED' THEN
              Process(IsClosed)
            ELSE IF st = 'ISLOCKED' THEN
              Process(IsLocked)
            ELSE IF st = 'ISUNLOCKED' THEN
              Process(IsUnLocked)
            ELSE IF st = 'ISEDIBLE' THEN
              Process(IsEdible)
            ELSE IF st = 'ISDRINKABLE' THEN
              Process(IsDrinkable)
            ELSE IF st = 'ISPOISONOUS' THEN
              Process(IsPoisonous)
            ELSE IF st = 'ISMOVABLE' THEN
              Process(IsMovable)
            ELSE IF st = 'NOUNPRESENT' THEN
              Process(NOUNPresent)
            ELSE IF st = 'NOUNISWEARING' THEN
              Process(NOUNIsWearing)
            ELSE IF st = 'NOUNISCARRYING' THEN
              Process(NOUNIsCarrying)
            ELSE IF st = 'NOUNISNOWHERE' THEN
              Process(NOUNIsNowhere)
            ELSE IF st = 'NOUNISSOMEWHERE' THEN
              Process(NOUNIsSomewhere)
            ELSE IF st = 'NOUNINROOM' THEN
              Process(NOUNInRoom)
            ELSE IF st = 'NOUNISLOCATED' THEN
              Process(NOUNIsLocated)
            ELSE IF st = 'NOUNISON' THEN
              Process(NOUNIsON)
            ELSE IF st = 'NOUNISOFF' THEN
              Process(NOUNIsOFF)
            ELSE IF st = 'NOUNISOPEN' THEN
              Process(NOUNIsOpen)
            ELSE IF st = 'NOUNISCLOSED' THEN
              Process(NOUNIsClosed)
            ELSE IF st = 'NOUNISLOCKED' THEN
              Process(NOUNIsLocked)
            ELSE IF st = 'NOUNISUNLOCKED' THEN
              Process(NOUNIsUnLocked)
            ELSE IF st = 'NOUNISEDIBLE' THEN
              Process(NOUNIsEdible)
            ELSE IF st = 'NOUNISDRINKABLE' THEN
              Process(NOUNIsDrinkable)
            ELSE IF st = 'NOUNISPOISONOUS' THEN
              Process(NOUNIsPoisonous)
            ELSE IF st = 'NOUNISMOVABLE' THEN
              Process(NOUNIsMovable)
            ELSE IF st = 'NOUNPOINTSEQUALS' THEN
              Process(NOUNpointsEquals)
            ELSE IF st = 'NOUNPOINTSGT' THEN
              Process(NOUNpointsGT)
            ELSE IF st = 'NOUNPOINTSLT' THEN
              Process(NOUNpointsLT)
            ELSE IF st = 'NOUNWEIGHTEQUALS' THEN
              Process(NOUNweightEquals)
            ELSE IF st = 'NOUNWEIGHTGT' THEN
              Process(NOUNweightGT)
            ELSE IF st = 'NOUNWEIGHTLT' THEN
              Process(NOUNweightLT)
            ELSE IF st = 'FLAGON' THEN
              Process(FlagON)
            ELSE IF st = 'FLAGOFF' THEN
              Process(FlagOFF)
            ELSE IF st = 'SCOREEQUALS' THEN
              Process(ScoreEquals)
            ELSE IF st = 'SCOREGT' THEN
              Process(ScoreGT)
            ELSE IF st = 'SCORELT' THEN
              Process(ScoreLT)
            ELSE IF st = 'NUMBEREQUALS' THEN
              Process(NumberEquals)
            ELSE IF st = 'NUMBERGT' THEN
              Process(NumberGT)
            ELSE IF st = 'NUMBERLT' THEN
              Process(NumberLT)
            ELSE IF st = 'TURNSEQUALS' THEN
              Process(TurnsEquals)
            ELSE IF st = 'TURNSGT' THEN
              Process(TurnsGT)
            ELSE IF st = 'TURNSLT' THEN
              Process(TurnsLT)
            ELSE IF st = 'ANSWERISCORRECT' THEN
              Process(AnswerIsCorrect)
            ELSE IF st = 'ANSWERISWRONG' THEN
              Process(AnswerIsWrong)
            ELSE IF st = 'COUNTEREQUALS' THEN
              Process(CounterEquals)
            ELSE IF st = 'COUNTERGT' THEN
              Process(CounterGT)
            ELSE IF st = 'COUNTERLT' THEN
              Process(CounterLT)
            ELSE IF st = 'VARIABLEEQUALS' THEN
              Process(VariableEquals)
            ELSE IF st = 'VARIABLEGT' THEN
              Process(VariableGT)
            ELSE IF st = 'VARIABLELT' THEN
              Process(VariableLT)
            ELSE IF st = 'CHANCE' THEN
              Process(Chance)
            ELSE IF st = 'VARIABLECHANCE' THEN
              Process(VariableChance)
            ELSE IF st = 'COMPAREVARIABLES' THEN
              Process(CompareVariables)
            ELSE IF st = 'NAMEPRESENT' THEN
              Process(NamePresent)
            ELSE IF st = 'NAMEISNUMBER' THEN
              Process(NameIsNumber)
            ELSE IF st = 'NOUNISNUMBER' THEN
              Process(NOUNIsNumber)
            ELSE IF st = 'OBJECTISNUMBER' THEN
              Process(ObjectIsNumber)
            ELSE IF st = 'PROMPTFORYES' THEN
              Process(PromptForYES)
            ELSE IF st = 'PROMPTFORNO' THEN
              Process(PromptForNO)
            ELSE IF st = 'VERBISDIRECTION' THEN
              Process(VerbIsDirection)
            ELSE IF st = 'MAKEVARROOMNUM' THEN
              Process(MakeVarRoomNum)
            ELSE IF st = 'MAKEVARNOUNNUM' THEN
              Process(MakeVarNounNum)
            ELSE IF st = 'MAKEVAROBJECTNUM' THEN
              Process(MakeVarObjectNum)
            ELSE IF st = 'GOTOVARIABLEROOM' THEN
              Process(GoToVariableRoom)
            ELSE IF st = 'SENDTOVARIABLEROOM' THEN
              Process(SendToVariableRoom)
            ELSE IF st = 'GETVARIABLEIT' THEN
              Process(GetVariableIt)
            ELSE IF st = 'PRINTVARIABLEMESSAGE' THEN
              Process(PrintVariableMessage)
            ELSE IF st = 'NOUNISCREATURE' THEN
              Process(NounIsCreature)
            ELSE IF st = 'OBJECTISCREATURE' THEN
              Process(ObjectIsCreature)
            ELSE IF st = 'OBJECTPRESENT' THEN
              Process(ObjectPresent)
            ELSE IF st = 'NOT' THEN {"NOT" is used in CMD file, LogicalNOT is token}
              Process(LogicalNOT)
            ELSE IF st = 'OR' THEN {"OR" is used in CMD file, LogicalOR is token}
              Process(LogicalOR)
            ELSE IF st = 'GOTOROOM' THEN
              Process(GoToRoom)
            ELSE IF st = 'GOTORANDOMROOM' THEN
              Process(GoToRandomRoom)
            ELSE IF st = 'GETIT' THEN
              Process(GetIt)
            ELSE IF st = 'SOMETHINGINSIDE' THEN
              Process(SomethingInside)
            ELSE IF st = 'SHOWCONTENTS' THEN
              Process(ShowContents)
            ELSE IF st = 'WEARIT' THEN
              Process(WearIt)
            ELSE IF st = 'DROPIT' THEN
              Process(DropIt)
            ELSE IF st = 'REMOVEIT' THEN
              Process(RemoveIt)
            ELSE IF st = 'GETNOUN' THEN
              Process(GetNOUN)
            ELSE IF st = 'WEARNOUN' THEN
              Process(WearNOUN)
            ELSE IF st = 'DROPNOUN' THEN
              Process(DropNOUN)
            ELSE IF st = 'REMOVENOUN' THEN
              Process(RemoveNOUN)
            ELSE IF st = 'ADDTOGROUP' THEN
              Process(AddToGroup)
            ELSE IF st = 'REMOVEFROMGROUP' THEN
              Process(RemoveFromGroup)
            ELSE IF st = 'MOVETHEGROUP' THEN
              Process(MoveTheGroup)
            ELSE IF st = 'REDIRECTTO' THEN
              BEGIN
                Process(ReDirectTo); {store token}
                sentence := But_First(sentence); {strip off REDIRECTTO}
                Handle_Word_Combinations(sentence);
                CheckForName(sentence);
                Parse(sentence, verb, noun, prep, object_word, ErrorInCommand);
                IF verb = '' THEN verb := 'ANY';
                IF noun = '' THEN noun := 'ANY';
                IF object_word = '' THEN object_word := 'ANY';
                n1 := Verb_Number(verb);
                IF NameNum <> 0 THEN n1 := NameNum; {Name used for sort key}
                n1 := n1+2000;    {make n1 > 1999 to signify re-direction}
                Last_CMD := Last_CMD+1; {go to next command to store data}
                IF Last_CMD <= MaxCommand THEN
                  BEGIN           {store data on VERB-NOUN-OBJECT combination for re-direction}
                    SpecialCMD[Last_CMD]^.VerbNum := n1;
                    SpecialCMD[Last_CMD]^.VerbCMD := verb;
                    SpecialCMD[Last_CMD]^.NounCMD := noun;
                    SpecialCMD[Last_CMD]^.ObjectCMD := object_word;
                  END
                ELSE
                  BEGIN
                    WriteLn('Too many commands!  Processing halted');
                    Halt;
                  END;
              END                 {ReDirectTo}
            ELSE IF st = 'RANDOMMESSAGE' THEN
              Process(RandomMessage)
            ELSE IF st = 'OPENIT' THEN
              Process(OpenIt)
            ELSE IF st = 'CLOSEIT' THEN
              Process(CloseIt)
            ELSE IF st = 'LOCKIT' THEN
              Process(LockIt)
            ELSE IF st = 'UNLOCKIT' THEN
              Process(UnlockIt)
            ELSE IF st = 'OPENNOUN' THEN
              Process(OpenNOUN)
            ELSE IF st = 'CLOSENOUN' THEN
              Process(CloseNOUN)
            ELSE IF st = 'LOCKNOUN' THEN
              Process(LockNOUN)
            ELSE IF st = 'UNLOCKNOUN' THEN
              Process(UnlockNOUN)
            ELSE IF st = 'DROPEVERYTHING' THEN
              Process(DropEverything)
            ELSE IF st = 'REMOVEEVERYTHING' THEN
              Process(RemoveEverything)
            ELSE IF st = 'KILLPLAYER' THEN
              Process(KillPlayer)
            ELSE IF st = 'PUTINCURRENTROOM' THEN
              Process(PutInCurrentRoom)
            ELSE IF st = 'SENDTOROOM' THEN
              Process(SendToRoom)
            ELSE IF st = 'PUTNOUNINCURRENTROOM' THEN
              Process(PutNOUNInCurrentRoom)
            ELSE IF st = 'SENDNOUNTOROOM' THEN
              Process(SendNOUNToRoom)
            ELSE IF st = 'SENDALLTOROOM' THEN
              Process(SendAllToRoom)
            ELSE IF st = 'SENDTREASURESTOROOM' THEN
              Process(SendTreasuresToRoom)
            ELSE IF st = 'RELOCATEALL' THEN
              Process(RelocateAll)
            ELSE IF st = 'DESTROY' THEN
              Process(Destroy)
            ELSE IF st = 'DESTROYNOUN' THEN
              Process(DestroyNOUN)
            ELSE IF st = 'SWAPLOCATIONS' THEN
              Process(SwapLocations)
            ELSE IF st = 'SENDTOITEM' THEN
              Process(SendToItem)
            ELSE IF st = 'SENDNOUNTOITEM' THEN
              Process(SendNOUNToItem)
            ELSE IF st = 'SHOWSCORE' THEN
              Process(ShowScore)
            ELSE IF st = 'PLUSSCORE' THEN
              Process(PlusScore)
            ELSE IF st = 'MINUSSCORE' THEN
              Process(MinusScore)
            ELSE IF st = 'SHOWINVENTORY' THEN
              Process(ShowInventory)
            ELSE IF st = 'WAITFORRETURN' THEN
              Process(WaitForReturn)
            ELSE IF st = 'TIMEPASSES' THEN
              Process(TimePasses)
            ELSE IF st = 'DELAY' THEN
              Process(xDelay)
            ELSE IF st = 'CLEARSCREEN' THEN
              Process(CLEARSCREEN)
            ELSE IF st = 'DESCRIBETHING' THEN
              Process(DescribeThing)
            ELSE IF st = 'LOOKATROOM' THEN
              Process(LookAtRoom)
            ELSE IF st = 'PRINTMESSAGE' THEN
                Process(PrintMessage)
            ELSE IF st = 'BLANKLINE' THEN
              Process(BlankLine)
            ELSE IF st = 'TONE' THEN
              Process(Tone)
            ELSE IF st = 'GETNUMBERINPUT' THEN
              Process(GetNumberInput)
            ELSE IF st = 'ASKQUESTION' THEN
              Process(AskQuestion)
            ELSE IF st = 'CHANGEPASSAGEWAY' THEN
              Process(ChangePassageway)
            ELSE IF st = 'TURNFLAGON' THEN
              Process(TurnFlagON)
            ELSE IF st = 'TURNFLAGOFF' THEN
              Process(TurnFlagOFF)
            ELSE IF st = 'TOGGLEFLAG' THEN
              Process(ToggleFlag)
            ELSE IF st = 'TURNCOUNTERON' THEN
              Process(TurnCounterON)
            ELSE IF st = 'TURNCOUNTEROFF' THEN
              Process(TurnCounterOFF)
            ELSE IF st = 'SETVARIABLETO' THEN
              Process(SetVariableTo)
            ELSE IF st = 'ADDTOVARIABLE' THEN
              Process(AddToVariable)
            ELSE IF st = 'SUBTRACTFROMVARIABLE' THEN
              Process(SubtractFromVariable)
            ELSE IF st = 'ADDVARIABLES' THEN
              Process(AddVariables)
            ELSE IF st = 'SUBTRACTVARIABLES' THEN
              Process(SubtractVariables)
            ELSE IF st = 'RANDOMVARIABLE' THEN
              Process(RandomVariable)
            ELSE IF st = 'NOUNTOVARIABLE' THEN
              Process(NounToVariable)
            ELSE IF st = 'OBJECTTOVARIABLE' THEN
              Process(ObjectToVariable)
            ELSE IF st = 'QUITTHISCMD' THEN
              Process(QuitThisCMD)
            ELSE IF st = 'QUITALLCMDS' THEN
              Process(QuitAllCMDs)
            ELSE IF st = 'DONEWITHTURN' THEN
              Process(DoneWithTurn)
            ELSE IF st = 'WINGAME' THEN
              Process(WinGame)
            ELSE IF st = 'ENDGAME' THEN
              Process(EndGame)
            ELSE IF (Copy(st, 1, 4) <> 'END_') THEN
              BEGIN
                WriteLn('Illegal Token: ', sentence);
                WriteLn('For Command: ', verb, ' ', noun, ' ', object_word);
                WriteLn;
              END;
          UNTIL (Copy(st, 1, 4) = 'END_');
        END;                      {IF COMMAND}

DoneWithFile:
    UNTIL (POS('END OF FILE', sentence) <> 0) OR (EOF(datafile));
    Close(datafile);
    {Now determine indices for index sequential searches of SpecialCMDs}
    IF ErrorInCommand THEN Last_CMD := Last_CMD-1;
    {If last command was illegal, then ignore it}
    FOR i := 1 TO Last_CMD DO
      BEGIN
        j := SpecialCMD[i]^.VerbNum;
        IF j < 2000 THEN
          BEGIN                   {Not a ReDirectTo command}
            IF i < StartingIndex[j] THEN StartingIndex[j] := i;
            {get minimum starting index for each verb}
            IF i > EndingIndex[j] THEN EndingIndex[j] := i;
            {get maximum ending index for each verb}
          END;
      END;                        {i := 1 TO Last_CMD}
Exit:
    Skip_A_Line := True;
  END;                            {READ_SPECIAL_CMDS}


